'''This file defines the interface for getting input from the user or AI.'''

from pygame import draw, key, joystick, locals
from math   import sin, cos, atan2

from locals  import *
from pointer import *

inputs     = []
joysticks  = []

class Input:
    '''A generic input class, which translates and forwards commands by the
    player to a player-controlled character.'''
    def __init__(self, input_type, description = None):
        self.input_type  = input_type
        self.description = description
    
    def assign_mage(self, mage):
        '''Assigns a mage to the input method.'''
        self.mage = mage
        
    def get_axes(self):
        '''Checks the value of the axes. It should be called after the event
        queue has been pumped.
        '''
        pass

    def get_actions(self, event_list):
        '''Gets information about occurrance of actions'''
        pass

class Joystick(Input):
    def __init__(self, joystick, keys):
        '''When created, this class receives an instance of the joystick class.
        The class assumes that the axes 0 and 1 are the intended directional
        axes.
        keys - A map of button IDs to actions. You can see the list of actions
        at locals.py.'''
        Input.__init__(self, JOYSTICK, "Joystick "+str(joystick.get_id()))
        self.id    = joystick.get_id()
        self.input = joystick
        self.keys  = keys
    
    def get_axes(self):
        return (self.input.get_axis(0), self.input.get_axis(1))

    def get_actions(self, event_list):
        buttons = [event.button for event in event_list if event.joy == self.id]
        actions = []
        for action in self.keys:
            if buttons.count(action) > 0:
                actions.append(action)
        return actions

class Keyboard(Input):
    def __init__(self, keys, directional, description = None):
        '''This type of input needs the definition of both an action-key map and
        a direction-key map.
        keys - A map of actions to key IDs. You can see the list of actions at
        locals.py
        directional - A map of directions to key IDs. You can see the list of
        directions at locals.py'''
        Input.__init__(self, KEYBOARD, description)
        self.keys        = keys
        self.directional = directional
    
    def get_axes(self):
        keyboard_state = key.get_pressed()
        if keyboard_state[self.directional[UP]]:
            y = -1
        elif keyboard_state[self.directional[DOWN]]:
            y = 1
        else:
            y = 0
        if keyboard_state[self.directional[RIGHT]]:
            x = 1
        elif keyboard_state[self.directional[LEFT]]:
            x = -1
        else:
            x = 0
        if x == 0 and y == 0:
            return (0, 0)
        d = atan2(y, x)
        return (cos(d), sin(d))

    def get_actions(self, event_list):
        key_presses = [event.key for event in event_list]
        actions = []
        for action in xrange(len(self.keys)):
            if key_presses.count(self.keys[action]) > 0:
                actions.append(action)
        return actions

def input_init():
    '''Initializes the joysticks and adds them to a global list.'''
    global joysticks, inputs      
    for x in xrange(0, joystick.get_count()):
        j = joystick.Joystick(x)
        j.init()
        joysticks.append(j)
    print "Found",len(joysticks),"joysticks."

    for j in joysticks:
        inputs.append(Joystick(j, [0,1,2,3,4,5]))
    inputs.append(Keyboard([K_v, K_b, K_n, K_m, K_ESCAPE, K_PRINT], [K_w, K_d, K_s, K_a], "Keyboard: wasd + vbnm"))
    inputs.append(Keyboard([K_u, K_i, K_o, K_p, K_ESCAPE, K_PRINT], [K_UP, K_RIGHT, K_DOWN, K_LEFT], "Keyboard: Arrow keys + uiop"))

    for i in inputs:
        print i.description

